local skel = fk.CreateSkill {
  name = "emo__xiegong",
}

Fk:loadTranslationTable{
  ["emo__xiegong"] = "械攻",
  [":emo__xiegong"] = "每当一张装备牌进入弃牌堆时，你获得1点铸造值。每当你使用装备牌后，重铸之，<a href='emo__xiegong_href'>根据类型</a>你获得+1属性。每回合结束时，你可以消耗3点铸造值进行发明。",

  ["emo__xiegong_href"] = "武器/进攻马：+1攻击范围；防具/防御马：+1手牌上限；宝物：+1摸牌阶段摸牌数。",
  ["#emo__xiegong-build"] = "【大攻车】选择一个时机，随机获得一项此时机的效果",
  ["#emo__xiegong-ask-upgrade"] = "你可以消耗3点铸造值进行发明！",

  ["@[emosv]property"] = "铸造",
  ["sv_atk"] = "攻",
  [":sv_atk"] = "攻击范围",
  ["sv_def"] = "守",
  [":sv_def"] = "手牌上限",
  ["sv_food"] = "粮",
  [":sv_food"] = "摸牌数",

  ["sv_startEffect"] = "平台",
  [":sv_startEffect"] = "准备阶段",
  ["sv_damageEffect"] = "车厢",
  [":sv_damageEffect"] = "受到伤害后",
  ["sv_activeEffect"] = "武器",
  [":sv_activeEffect"] = "出牌阶段限一次",
  ["sv_stateEffect"] = "装甲",
  [":sv_stateEffect"] = "被动效果",
}

local effect_map = {
  sv_startEffect = {"sv_wing", "sv_sail", "sv_drum"},
  sv_damageEffect = {"sv_cloud", "sv_copper", "sv_steel"},
  sv_activeEffect = {"sv_chain", "sv_gun", "sv_hammer"},
  sv_stateEffect = {"sv_horse", "sv_sheild", "sv_bagua"},
}

Fk:loadTranslationTable{
  ["sv_wing"] = "鷞鸠翼",
  [":sv_wing"] = "获得一张锦囊牌",
  ["sv_sail"] = "扬幡",
  [":sv_sail"] = "观星四张",
  ["sv_drum"] = "战鼓",
  [":sv_drum"] = "获得一个额外出牌阶段",

  ["sv_cloud"] = "云纹车厢",
  [":sv_cloud"] = "视为对伤害来源使用一张【杀】",
  ["sv_copper"] = "鍮石车厢",
  [":sv_copper"] = "摸两张牌",
  ["sv_steel"] = "精钢车厢",
  [":sv_steel"] = "获得2点铸造值",

  ["sv_chain"] = "穿云锁",
  [":sv_chain"] = "横置或重置至多两名角色",
  ["sv_gun"] = "神火铳",
  [":sv_gun"] = "视为使用一张不计次数的火【杀】",
  ["sv_hammer"] = "攻城锤",
  [":sv_hammer"] = "弃置一名其他角色随机两张牌",

  ["sv_horse"] = "拒马",
  [":sv_horse"] = "其他角色计算与你距离+2",
  ["sv_sheild"] = "浑天盾",
  [":sv_sheild"] = "你不为♠伤害牌的合法目标",
  ["sv_bagua"] = "八卦台",
  [":sv_bagua"] = "邻家的手牌对你可见",
}

skel:addEffect("active", {
  anim_type = "offensive",
  min_target_num = 1,
  interaction = function(self, player)
    local mark = player:getMark("@[emosv]property")
    local used = player:getTableMark("siege_vehicles_used-phase")
    if mark ~= 0 then
      local choices = table.filter(mark.sv_activeEffect, function (e) return not table.contains(used, e) end)
      if #choices > 0 then
        return UI.ComboBox { choices = choices }
      end
    end
  end,
  prompt = function (self)
    local choice = self.interaction.data
    if type(choice) == "string" then
      return Fk:translate(":" .. choice)
    end
    return " "
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, player, to, selected)
    if self.interaction.data == "sv_chain" then
      return #selected < 2
    elseif self.interaction.data == "sv_hammer" then
      return #selected == 0 and player ~= to and not to:isNude()
    else
      local slash = Fk:cloneCard("fire__slash")
      slash.skillName = skel.name
      return #selected < slash.skill:getMaxTargetNum(player, slash) and not player:prohibitUse(slash)
      and not player:isProhibited(to, slash)
    end
  end,
  can_use = function(self, player)
    local mark = player:getMark("@[emosv]property")
    local used = player:getTableMark("siege_vehicles_used-phase")
    if mark ~= 0 then
      return table.find(mark.sv_activeEffect, function (e) return not table.contains(used, e) end)
    end
  end,
  on_use = function(self, room, effect)
    local player = effect.from
    local tos = effect.tos
    room:sortByAction(tos)
    local choice = self.interaction.data
    room:addTableMark(player, "siege_vehicles_used-phase", choice)
    if choice == "sv_chain" then
      for _, p in ipairs(tos) do
        if not p.dead then
          p:setChainState(not p.chained)
        end
      end
    elseif choice == "sv_hammer" then
      local to = tos[1]
      local cards = to:getCardIds("he")
      if #cards > 0 then
        room:throwCard(table.random(cards, 2), skel.name, to, player)
      end
    else
      room:useVirtualCard("fire__slash", nil, player, tos, skel.name, true)
    end
  end,
})

skel:addEffect(fk.EventPhaseStart, {
  anim_type = "offensive",
  can_trigger = function (self, event, target, player, data)
    if target == player and player:hasSkill(skel.name) then
      local mark = player:getMark("@[emosv]property")
      return player.phase == Player.Start and #mark.sv_startEffect > 0
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("@[emosv]property")
    -- 固定结算顺序
    local effects = table.filter({"sv_wing", "sv_sail", "sv_drum"}, function (e)
      return table.contains(mark.sv_startEffect, e)
    end)
    for _, effect in ipairs(effects) do
      if player.dead then break end
      if effect == "sv_wing" then
        local ids = room:getCardsFromPileByRule(".|.|.|.|.|trick")
        if #ids > 0 then
          room:moveCardTo(ids, Player.Hand, player, fk.ReasonJustMove, skel.name, nil, false)
        end
      elseif effect == "sv_sail" then
        room:askToGuanxing(player, { cards = room:getNCards(4) })
      else
        player:gainAnExtraPhase(Player.Play, skel.name)
      end
    end
  end,
})

skel:addEffect(fk.Damaged, {
  anim_type = "defensive",
  can_trigger = function (self, event, target, player, data)
    if target == player and player:hasSkill(skel.name) then
      local mark = player:getMark("@[emosv]property")
      return #mark.sv_damageEffect > 0
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("@[emosv]property")
    -- 固定结算顺序
    local effects = table.filter({"sv_steel", "sv_copper", "sv_cloud"}, function (e)
      return table.contains(mark.sv_damageEffect, e)
    end)
    for _, effect in ipairs(effects) do
      if player.dead then break end
      if effect == "sv_copper" then
        player:drawCards(2, skel.name)
      elseif effect == "sv_steel" then
        room:addPlayerMark(player, "emo__construct", 2)
      else
        local from = data.from
        if from and not from.dead and from ~= player then
          room:useVirtualCard("slash", nil, player, from, skel.name, true)
        end
      end
    end
  end,
})


skel:addEffect(fk.CardUseFinished, {
  anim_type = "drawcard",
  can_trigger = function (self, event, target, player, data)
    if target == player and player:hasSkill(skel.name) and data.card.type == Card.TypeEquip then
      return table.contains(player:getCardIds("e"), data.card:getEffectiveId())
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local cid = data.card:getEffectiveId()
    local card = Fk:getCardById(cid)
    room:recastCard({cid}, player, skel.name)
    if player.dead then return end
    local mark = player:getMark("@[emosv]property")
    if mark ~= 0 then
      if card.sub_type == Card.SubtypeWeapon or card.sub_type == Card.SubtypeOffensiveRide then
        mark.sv_atk = mark.sv_atk + 1
      elseif card.sub_type == Card.SubtypeTreasure then
        mark.sv_food = mark.sv_food + 1
      else
        mark.sv_def = mark.sv_def + 1
      end
      room:setPlayerMark(player, "@[emosv]property", mark)
    end
  end,
})

skel:addEffect(fk.TurnEnd, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(skel.name) and player:getMark("emo__construct") >= 3 then
      local mark = player:getMark("@[emosv]property")
      if mark == 0 then return false end
      for _, v in pairs(mark) do
        if type(v) == "table" and #v < 3 then
          return true
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askToSkillInvoke(player, {skill_name = skel.name, prompt = "#emo__xiegong-ask-upgrade"})
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:removePlayerMark(player, "emo__construct", 3)
    local mark = player:getMark("@[emosv]property")
    if mark == 0 then return end
    local all_choices = {}
    local choices = {}
    for name, list in pairs(effect_map) do
      if #list > #mark[name] then
        table.insert(choices, name)
      end
      table.insert(all_choices, name)
    end
    if #choices == 0 then return end
    local choice = room:askToChoice(player, {
      choices = choices, skill_name = skel.name, prompt = "#emo__xiegong-build", all_choices = all_choices, detailed = true,
    })
    choices = table.filter(effect_map[choice], function (e)
      return not table.contains(mark[choice], e)
    end)
    table.insert(mark[choice], 1, table.random(choices))
    room:setPlayerMark(player, "@[emosv]property", mark)
  end,
})

skel:addEffect(fk.AfterCardsMove, {
  anim_type = "control",
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(skel.name) then return false end
    for _, move in ipairs(data) do
      if move.toArea == Card.DiscardPile then
        for _, info in ipairs(move.moveInfo) do
          if Fk:getCardById(info.cardId).type == Card.TypeEquip then
            return true
          end
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
     for _, move in ipairs(data) do
      if move.toArea == Card.DiscardPile then
        for _, info in ipairs(move.moveInfo) do
          if Fk:getCardById(info.cardId).type == Card.TypeEquip then
            n = n + 1
          end
        end
      end
    end
    room:addPlayerMark(player, "emo__construct", n)
  end,
})

skel:addEffect("distance", {
  correct_func = function(self, from, to)
    if to and from ~= to then
      local mark = to:getMark("@[emosv]property")
      if mark ~= 0 and table.contains(mark.sv_stateEffect, "sv_horse") then
        return 2
      end
    end
  end,
})

skel:addEffect("prohibit", {
  is_prohibited = function(self, from, to, card)
    if from and to and card and from ~= to then
      if card.suit == Card.Spade and card.is_damage_card then
        local mark = to:getMark("@[emosv]property")
        return mark ~= 0 and table.contains(mark.sv_stateEffect, "sv_sheild")
      end
    end
  end,
})

skel:addEffect("visibility", {
  card_visible = function (self, player, card)
    local mark = player:getMark("@[emosv]property")
    if mark ~= 0 and table.contains(mark.sv_stateEffect, "sv_bagua") then
      local owner = Fk:currentRoom():getCardOwner(card)
      if owner and owner ~= player then
        if owner:getNextAlive() == player or player:getNextAlive() == owner then
          return true
        end
      end
    end
  end,
})

skel:addEffect(fk.DrawNCards, {
  anim_type = "drawcard",
  can_trigger = function (self, event, target, player, data)
    if target == player and player:hasSkill(skel.name) then
      local mark = player:getMark("@[emosv]property")
      return mark ~= 0 and mark.sv_food
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local mark = player:getMark("@[emosv]property")
    data.n = data.n + mark.sv_food
  end,
})

skel:addEffect("maxcards", {
  correct_func = function (self, player)
    local mark = player:getMark("@[emosv]property")
    if mark ~= 0 then
      return mark.sv_def
    end
  end,
})

skel:addEffect("atkrange", {
  correct_func = function (self, player)
    local mark = player:getMark("@[emosv]property")
    if mark ~= 0 then
      return mark.sv_atk
    end
  end,
})

Fk:addQmlMark{
  name = "emosv",
  qml_path = "packages/emopack/qml/SVBox",
  how_to_show = function(_, _, player)
    return tostring(player:getMark("emo__construct"))
  end,
}

skel:addAcquireEffect(function (self, player, is_start)
  player.room:setPlayerMark(player, "@[emosv]property", {
    sv_atk = 0, sv_def = 0, sv_food = 0,
    sv_startEffect = {},
    sv_damageEffect = {},
    sv_activeEffect = {},
    sv_stateEffect = {},
  })
end)

skel:addLoseEffect(function (self, player, is_death)
  player.room:setPlayerMark(player, "@[emosv]property", 0)
  player.room:setPlayerMark(player, "emo__construct", 0)
end)

return skel
